<?php
/**
 * Created by PhpStorm.
 * User: jaylen
 * Date: 2020-10-29
 * Time: 15:45
 */

namespace app\common\model\traits;


use app\common\exception\ParameterException;
use app\common\exception\ProductException;
use app\common\model\Order;
use app\common\model\ShopProductParameters;
use app\common\model\ShopProductProperty;
use app\common\model\ShopProductSpecs;
use app\common\model\ShopProductSpecsProperty;
use think\facade\Db;

trait HandleShopProduct
{
    /**
     * 通过订单传递的信息获取规格数据
     * @param $specs
     */
    public static function getSpecsDataWithOrder($specs)
    {
        $specs_data = [];
        $amount = 0.0;

//        $specs_ids = array_column($specs, 'specs_id');
        $product_ids = array_column($specs, 'product_id');

        // 对ids去重
//        $specs_ids = array_values(array_unique($specs_ids));
        $product_ids = array_values(array_unique($product_ids));

        // 根据ids获取数据
        $product_data = static::with(['specs' => function($query) {
            $query->with(['property' => function($query) {
                $query->with(['property']);
            }]);
        }])->where([['id','in',$product_ids],['status','=',1]])
            ->field(['id','title','main_image','virtual_product'])
            ->select();

        if ($product_data->isEmpty()) {
            throw new ProductException();
        }

        $product_data = $product_data->toArray();


        foreach ($specs as $s_item) {
            // 根据product_id和specs_id 获取商品数据
            $product = array_filter($product_data, function ($p_item) use ($s_item) {
                if ($p_item['id'] == $s_item['product_id']) {
                    return true;
                }
            });
            $product = array_values($product)[0] ?? ['specs' => []];
            $product_specs = array_filter($product['specs'], function ($ss_item) use ($s_item) {
                if ($s_item['specs_id'] == $ss_item['id']) {
                    return true;
                }
            });
            $product_specs = array_values($product_specs)[0] ?? [];
            if (empty($product_specs)) {
                throw new ProductException();
            }

            // 判断库存
            if ($s_item['count'] > $product_specs['stock']) {
                throw new ProductException([
                    'code' => 401,
                    'msg' => $product['title'] . ' 商品库存不足',
                    'errorCode' => 40301
                ]);
            }

            $specs_data_array = [];

            foreach ($product_specs['property'] as $psp_item) {
                $specs_data_array[$psp_item['property']['name']] = $psp_item['value'];
            }

            // 重组商品数据
            $specs_data[] = [
                'specs_id' => $product_specs['id'],
                'product_id' => $product['id'],
                'virtual_product' => $product['virtual_product'],
                'specs_data' => json_encode($specs_data_array, JSON_UNESCAPED_UNICODE),
                'product_price' => $product_specs['selling_price'],
                'product_count' => $s_item['count'],
                'product_title' => $product['title'],
                'product_image' => $product_specs['product_image']['prefix'] ?: $product['main_image']['prefix'][0]
            ];

            // 计算商品总价
            $amount += ($product_specs['selling_price'] * $s_item['count']);
        }

        return [
            'specs' => $specs_data,
            'amount' => $amount
        ];
        
    }

    /**
     * 根据规格id获取对应的库存
     * @param $specs_id
     * @return array
     */
    public static function getSpecsStockData($specs_id)
    {
        $specs_id = explode(',',$specs_id);
        if (empty($specs_id) || !is_array($specs_id)) {
            throw new ParameterException();
        }
        $specs = ShopProductSpecs::where([['id','in',$specs_id]])
            ->field('id,stock')
            ->select();
        $specs = $specs->isEmpty() ? [] : $specs->toArray();

//        if (empty($specs) || count($specs) != count($specs_id)) {
//            throw new ProductException();
//        }

        // 重组数据，specs_id作为键，库存作为值
        $specs_stock = [];
        foreach ($specs as $s_item) {
            $specs_stock[$s_item['id']] = $s_item['stock'];
        }

        return $specs_stock;

    }

    /**
     * 更新商品的销售数量
     * @param $order_id
     */
    public static function updateShopProductSalesVolume($order_id)
    {
        // 根据订单id查找出对应的商品id
        $order_data = Order::with(['product' => function($query) {
            $query->field('order_id,product_id');
        }])
            ->where([['id','=',$order_id]])
            ->field('id')
            ->find();

        //  如果不为空才进行对销量进行处理
        if (!empty($order_data)) {
            $order_data = $order_data->toArray();
            // 取出当地订单对应对商品id
            $product_ids = array_column($order_data['product'],'product_id');
            // 去除重复的商品id
            $product_ids = array_unique($product_ids);

            $product_data = array_map(function ($item) {
                return [
                    'id' => $item,
                    'sales_volume' => Db::raw('sales_volume+1')
                ];
            }, $product_ids);

            (new static)->saveAll($product_data);
        }
    }


    /**
     * 分离前端提交的数据
     * @param $data
     * @return array
     */
    private static function splitSubmitData($data)
    {
        // 分离数据，将数据分为基本数据，新增数据，修改更新数据，属性数据，规格数据
        $base_data = [];
        $property_data = [];
        $specs_data = [];
        $parameters_data = [];

        // 基础数据
        $base_data['title'] = $data['title'];
        $base_data['main_image'] = $data['main_image'];
        $base_data['keyword'] = $data['keyword'];
        $base_data['desc'] = $data['desc'];
        $base_data['content'] = $data['content'];
        $base_data['virtual_product'] = $data['virtual_product'];
        $base_data['virtual_sales_volume'] = $data['virtual_sales_volume'];
        $base_data['category_id'] = $data['category_id'];
        $base_data['sort'] = $data['sort'];
        $base_data['recomm'] = $data['recomm'];
        $base_data['status'] = $data['status'];

        // 属性数据
        $property_data = [];
        foreach ($data['property'] as $property_item) {
            if (empty($property_item['name'])) {
                continue ;
            }
            $property_data[] = $property_item;
        }

        // 规格属性
        $all_property = array_column($property_data, 'prop');
        $specs_data = [];
        foreach ($data['specs'] as $spec_item) {
            $is_empty = false;
            foreach ($all_property as $prop_item) {
                if (empty($spec_item[$prop_item])) {
                    $is_empty = true;
                    return ;
                }
            }
            if (!$is_empty) {
                $specs_data[] = $spec_item;
            }
        }

        // 产品参数
        $parameters_data = [];
        foreach ($data['parameters'] as $parameter_item) {
            if (empty($parameter_item['name']) || empty($parameter_item['value'])) {
                continue ;
            }
            $parameters_data[] = $parameter_item;
        }

        return [
            'base' => $base_data,
            'property' => $property_data,
            'specs' => $specs_data,
            'parameters' => $parameters_data
        ];
    }

    /**
     * 生成保存到数据库的属性数据
     * @param $product_id
     * @param $property_data
     * @return array
     */
    private static function generatePropertyData($product_id, $property_data)
    {
        if (!empty($property_data)) {
            $property_index = 1;
            $property = [];
            $property_prop = [];
            foreach ($property_data as $prop_item) {
                $property_id = (int)"${product_id}${property_index}1";
                $property [] = [
                    'id' => $property_id, // 添加属性id字段数据
                    'name' => $prop_item['name']
                ];
                $property_prop[$prop_item['prop']] = $property_id;
                $property_index++;
            }
        } else {
            return [];
        }

        return [
            'data' => $property,
            'prop' => $property_prop
        ];
    }

    /**
     * 生成保存到数据库的规格数据
     * @param $product_id
     * @param $property_prop_data
     * @param $specs_data
     * @return array
     */
    private static function generateSpecsData($product_id, $property_prop_data, $specs_data)
    {
        if (!empty($specs_data)) {
            $specs_index = 1;
            $specs = [];
            $specs_property = [];

            foreach ($specs_data as $specs_item) {
                $specs_id = (int)"${product_id}${specs_index}2";
                $specs[] = [
                    'id' => $specs_id,    // 添加规格id字段
                    'product_image' => $specs_item['product_image'],
                    'original_price' => $specs_item['original_price'],
                    'selling_price' => $specs_item['selling_price'],
                    'stock' => $specs_item['stock']
                ];

                foreach ($property_prop_data as $prop_key => $prop_value) {
                    $specs_property[] = [
                        'specs_id' => $specs_id,
                        'property_id' => $prop_value,
                        'value' => $specs_item[$prop_key]
                    ];
                }


                $specs_index++;
            }

        } else {
            return [];
        }

        return [
            'data' => $specs,
            'property' => $specs_property
        ];
    }

    /**
     * 生成分组选择器所需的数据结构
     * @param $product_data
     * @return array
     */
    private static function generaProductSpecsOptionsGroup($product_data)
    {
        $option_group_data = [];
        foreach ($product_data as $product_item) {
            // 判断是否为单规格
            if (count($product_item['specs']) == 1 && (isset($product_item['specs'][0]['property']) && empty($product_item['specs'][0]['property']))) {
                $label = $product_item['title'];
                $option_group_data[] = [
                    'id' => $product_item['specs'][0]['id'],
                    'label' => $label,
                    'child' => []
                ];
                continue;
            }
            $children_data = [];
            foreach ($product_item['specs'] as $specs_item) {
                $property = array_column($specs_item['property'], 'value');
                $property = implode(';', $property);
                $children_data[] = [
                    'id' => $specs_item['id'],
                    'label' => $product_item['title'] . ':' .  $property
                ];
            }
            $option_group_data[] = [
                'id' => $product_item['id'],
                'label' => $product_item['title'],
                'child' => $children_data
            ];
        }

        return $option_group_data;
    }

    /**
     * 获取需要删除的旧文件数据
     * @param $old_data
     * @return array
     */
    private static function deleteOldProductFileData($old_data, $new_data)
    {
        $needDeleteData = [];
        // 由于这里只有商品详情是包含其他文件，所以只要比较商品详情即可
        $old_content_data = static::getRichTextImage($old_data['content']);
        $new_content_data = static::getRichTextImage($new_data['content']);
        $needDeleteData = array_merge($needDeleteData, static::getDifferentFileWithArray($old_content_data, $new_content_data));

        return $needDeleteData;
    }

    /**
     * 删除就的商品属性和规格、产品参数
     * @param $product_id
     */
    private static function deleteOldPropertySpecs($product_id)
    {
        ShopProductProperty::where([['product_id','=',$product_id]])
            ->delete();

        $shopSpecsIDs = ShopProductSpecs::where([['product_id','=',$product_id]])
            ->column('id');
        ShopProductSpecs::where([['product_id','=',$product_id]])
            ->delete();
        ShopProductSpecsProperty::where([['specs_id','in',$shopSpecsIDs]])
            ->delete();

        ShopProductParameters::where([['product_id','=',$product_id]])
            ->delete();
    }
}